/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __A_MPU_H__
#define __A_MPU_H__

/* includes (standard library, system) ---------------------------------------*/
#include <stdint.h>
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/
#include <k_task.h>
/* includes (local) ----------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* defines -------------------------------------------------------------------*/

/*      attr macro defination                    privileged unprivileged */
#define MPU_ATTR_______ (0u << 24 | 1u << 28) /* none       none         */
#define MPU_ATTR_RW____ (1u << 24 | 1u << 28) /* RW         none         */
#define MPU_ATTR_RW_R__ (2u << 24 | 1u << 28) /* RW         R            */
#define MPU_ATTR_RW_RW_ (3u << 24 | 1u << 28) /* RW         RW           */
#define MPU_ATTR_R_____ (5u << 24 | 1u << 28) /* R          none         */
#define MPU_ATTR_R__R__ (6u << 24 | 1u << 28) /* R          R            */
#define MPU_ATTR_RWX___ (1u << 24)            /* RWX        none         */
#define MPU_ATTR_RWXR_X (2u << 24)            /* RWX        RX           */
#define MPU_ATTR_RWXRWX (3u << 24)            /* RWX        RWX          */
#define MPU_ATTR_R_X___ (5u << 24)            /* RX         none         */
#define MPU_ATTR_R_XR_X (6u << 24)            /* RX         RX           */

#define MPU_ATTR_STRONGLY (4u << 16) /* strongly always s, so set S */
#define MPU_ATTR_DEVICE   (5u << 16) /* device always s, so set S */
#define MPU_ATTR_WT       (2u << 16)
#define MPU_ATTR_WB       (3u << 16)

#define ERRNO_MPU_ILLEGAL_REGIONS   ERRNO_JOIN(MID_MPU, 1)
#define ERRNO_MPU_ILLEGAL_OPERATION ERRNO_JOIN(MID_MPU, 2)
#define ERRNO_MPU_UNAVAILABLE       ERRNO_JOIN(MID_MPU, 3)

/* typedefs ------------------------------------------------------------------*/

struct mpu_region {
    uint32_t addr;
    uint32_t size;
    uint32_t attr;
};

struct mpu_entry {
    uint32_t rbar;
    uint32_t rasr;
};

/* macro ---------------------------------------------------------------------*/
/* inlines -------------------------------------------------------------------*/
/* externs -------------------------------------------------------------------*/

extern task_id mpu_task_spawn(const char *name, uint8_t prio, uint32_t options, size_t stack_size,
                              int (*entry)(uintptr_t arg), uintptr_t arg,
                              struct mpu_region *regions);
extern int mpu_region_add(task_id task, uint32_t addr, uint32_t size, uint32_t attr);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __A_MPU_H__ */
